package {{package}}

{{#imports}}import {{import}}
{{/imports}}
{{#swagger2AnnotationLibrary}}
import io.swagger.v3.oas.annotations.*
import io.swagger.v3.oas.annotations.enums.*
import io.swagger.v3.oas.annotations.media.*
import io.swagger.v3.oas.annotations.responses.*
import io.swagger.v3.oas.annotations.security.*
{{/swagger2AnnotationLibrary}}
{{#swagger1AnnotationLibrary}}
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import io.swagger.annotations.ApiResponse
import io.swagger.annotations.ApiResponses
import io.swagger.annotations.Authorization
import io.swagger.annotations.AuthorizationScope
{{/swagger1AnnotationLibrary}}
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
{{#useResponseEntity}}
import org.springframework.http.ResponseEntity
{{/useResponseEntity}}

import org.springframework.web.bind.annotation.*
{{#useBeanValidation}}
import org.springframework.validation.annotation.Validated
{{/useBeanValidation}}
import org.springframework.web.context.request.NativeWebRequest
import org.springframework.beans.factory.annotation.Autowired
{{#useRequestMappingOnController}}
import {{#apiPackage}}{{.}}.{{/apiPackage}}{{classname}}Controller.Companion.BASE_PATH
{{/useRequestMappingOnController}}

{{#useBeanValidation}}
import {{javaxPackage}}.validation.Valid
import {{javaxPackage}}.validation.constraints.DecimalMax
import {{javaxPackage}}.validation.constraints.DecimalMin
import {{javaxPackage}}.validation.constraints.Email
import {{javaxPackage}}.validation.constraints.Max
import {{javaxPackage}}.validation.constraints.Min
import {{javaxPackage}}.validation.constraints.NotNull
import {{javaxPackage}}.validation.constraints.Pattern
import {{javaxPackage}}.validation.constraints.Size
{{/useBeanValidation}}

{{#reactive}}
import kotlinx.coroutines.flow.Flow
{{/reactive}}
import kotlin.collections.List
import kotlin.collections.Map

@RestController{{#beanQualifiers}}("{{package}}.{{classname}}Controller"){{/beanQualifiers}}
{{#useBeanValidation}}
@Validated
{{/useBeanValidation}}
{{#swagger1AnnotationLibrary}}
@Api(value = "{{{baseName}}}", description = "The {{{baseName}}} API")
{{/swagger1AnnotationLibrary}}
{{#useRequestMappingOnController}}
{{=<% %>=}}
@RequestMapping("\${openapi.<%title%>.base-path:\${api.base-path:$BASE_PATH}}")
<%={{ }}=%>
{{/useRequestMappingOnController}}
{{#operations}}
class {{classname}}Controller({{#serviceInterface}}@Autowired(required = true) val service: {{classname}}Service{{/serviceInterface}}) {

{{#operation}}
{{^useResponseEntity}}
    @ResponseStatus({{#springHttpStatus}}{{#responses.0}}{{{code}}}{{/responses.0}}{{/springHttpStatus}}){{!
}}{{/useResponseEntity}}{{!
}}{{#swagger2AnnotationLibrary}}{{!
}}    @Operation(
        summary = "{{{summary}}}",
        operationId = "{{{operationId}}}",
        description = """{{{unescapedNotes}}}""",
        responses = [{{#responses}}
            ApiResponse(responseCode = "{{{code}}}", description = "{{{message}}}"{{#baseType}}, content = [Content({{#isArray}}array = ArraySchema({{/isArray}}schema = Schema(implementation = {{{baseType}}}::class)){{#isArray}}){{/isArray}}]{{/baseType}}){{^-last}},{{/-last}}{{/responses}} ]{{#hasAuthMethods}},
        security = [ {{#authMethods}}SecurityRequirement(name = "{{name}}"{{#isOAuth}}, scopes = [ {{#scopes}}"{{scope}}"{{^-last}}, {{/-last}}{{/scopes}} ]{{/isOAuth}}){{^-last}},{{/-last}}{{/authMethods}} ]{{/hasAuthMethods}}
    ){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}
    @ApiOperation(
        value = "{{{summary}}}",
        nickname = "{{{operationId}}}",
        notes = "{{{notes}}}"{{#returnBaseType}},
        response = {{{.}}}::class{{/returnBaseType}}{{#returnContainer}},
        responseContainer = "{{{.}}}"{{/returnContainer}}{{#hasAuthMethods}},
        authorizations = [{{#authMethods}}Authorization(value = "{{name}}"{{#isOAuth}}, scopes = [{{#scopes}}AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{^-last}}, {{/-last}}{{/scopes}}]{{/isOAuth}}){{^-last}}, {{/-last}}{{/authMethods}}]{{/hasAuthMethods}})
    @ApiResponses(
        value = [{{#responses}}ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{.}}}::class{{/baseType}}{{#containerType}}, responseContainer = "{{{.}}}"{{/containerType}}){{^-last}},{{/-last}}{{/responses}}]){{/swagger1AnnotationLibrary}}
    @RequestMapping(
        method = [RequestMethod.{{httpMethod}}],
        value = [PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}} /* "{{#lambdaEscapeInNormalString}}{{{path}}}{{/lambdaEscapeInNormalString}}" */]{{#singleContentTypes}}{{#hasProduces}},
        produces = [{{#vendorExtensions.x-accepts}}"{{{.}}}"{{^-last}}, {{/-last}}{{/vendorExtensions.x-accepts}}]{{/hasProduces}}{{#hasConsumes}},
        consumes = "{{{vendorExtensions.x-content-type}}}"{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}},
        produces = [{{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}}]{{/hasProduces}}{{#hasConsumes}},
        consumes = [{{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}]{{/hasConsumes}}{{/singleContentTypes}}
    )
    {{#reactive}}{{^isArray}}suspend {{/isArray}}{{#isArray}}{{^useFlowForArrayReturnType}}suspend {{/useFlowForArrayReturnType}}{{/isArray}}{{/reactive}}fun {{operationId}}({{#allParams}}
        {{>queryParams}}{{>pathParams}}{{>headerParams}}{{>cookieParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}{{#includeHttpRequestContext}}{{#hasParams}},
        {{/hasParams}}{{#swagger1AnnotationLibrary}}@ApiParam(hidden = true) {{/swagger1AnnotationLibrary}}{{#swagger2AnnotationLibrary}}@Parameter(hidden = true) {{/swagger2AnnotationLibrary}}{{#reactive}}exchange: org.springframework.web.server.ServerWebExchange{{/reactive}}{{^reactive}}request: {{javaxPackage}}.servlet.http.HttpServletRequest{{/reactive}}{{/includeHttpRequestContext}}{{#hasParams}}
    {{/hasParams}}): {{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}} {
        return {{>returnValue}}
    }

{{/operation}}
    companion object {
        //for your own safety never directly reuse these path definitions in tests
    {{#useRequestMappingOnController}}
        const val BASE_PATH: String = "{{=<% %>=}}<%contextPath%><%={{ }}=%>"
    {{/useRequestMappingOnController}}
    {{#operation}}
        const val PATH_{{#lambda.uppercase}}{{#lambda.snakecase}}{{{operationId}}}{{/lambda.snakecase}}{{/lambda.uppercase}}: String = "{{{path}}}"
    {{/operation}}
    }
}
{{/operations}}
